package com.py.credit.service.impl;

import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.py.credit.common.ServiceException;
import com.py.credit.constant.ResourcePath;
import com.py.credit.dao.CreditReportDao;
import com.py.credit.dao.CreditReportLogDao;
import com.py.credit.entity.CreditReport;
import com.py.credit.entity.CreditReportLog;
import com.py.credit.entity.Hcbg;
import com.py.credit.entity.TableResult;
import com.py.credit.service.CreditReportService;
import com.py.credit.service.SSearchService;
import com.py.credit.service.ScontentService;
import com.py.credit.utils.DateUtils;
import com.py.credit.utils.PdfUtils;
import com.py.credit.utils.SQLBuilder;
import com.py.framework.core.common.Page;

@Service
public class CreditReportServiceImpl implements CreditReportService {
	@Autowired
	private CreditReportDao creditReportDao;
	@Autowired
	private CreditReportLogDao creditReportLogDao;

	@Autowired
	private ScontentService sContentService;

	@Autowired
	private SSearchService sSearchService;

	@Autowired
	private BgdzServiceImpl bgdzService;

	@Override
	public List<Map<String, Object>> getByConditionForPage(String kId, List<String> showColumns,
			String[] additionalColumns, String condition, Page page, String username, String deptname) {

		if (CollectionUtils.isEmpty(showColumns)) {

			throw new ServiceException("至少选择一列导出");

		}
		List<String> conditions = SQLBuilder.createConditionSql(condition);
		return creditReportDao.selectCreditReportListByConditionForPage(kId, showColumns, additionalColumns, conditions,
				page,username,deptname);
	}

	@Override
	public List<Map<String, Object>> getReportTrace(int reportId) {

		CreditReport report = creditReportDao.selectByPrimaryKey(reportId);

		List<Map<String, Object>> trace = new ArrayList<Map<String, Object>>();

		if (report != null) {

			List<CreditReportLog> logs = creditReportDao.selectLogByReportId(reportId);

			// 在线申请
			if (0 == report.getType()) {

				// 后台生成
			} else if (1 == report.getType()) {

				buildTrace(report, logs, trace);

			}

		}

		return trace;
	}

	private void buildTrace(CreditReport report, List<CreditReportLog> logs, List<Map<String, Object>> traces) {

		Map<String, Object> trace = new HashMap<String, Object>();
		Date generatorDate = report.getGeneratorDate();
		String generatorDept = report.getGeneratorDept();
		String generator = report.getGenerator();
		trace.put("time", DateUtils.dateParseString(generatorDate));
		trace.put("event", generatorDept + " 用户: " + generator + " 通过后台信用核查功能生成了核查报告");
		traces.add(trace);
		for (CreditReportLog log : logs) {

			Map<String, Object> downloadTrace = new HashMap<String, Object>();
			Date downlodDate = log.getDownlodDate();
			String userName = log.getUserName();
			downloadTrace.put("time", DateUtils.dateParseString(downlodDate));
			downloadTrace.put("event", "用户: " + userName + " 下载了报告");
			downloadTrace.put("detail", log.getId());
			traces.add(downloadTrace);

		}

	}

	@Override
	public void add(CreditReport report) {

		creditReportDao.insertSelective(report);
	}

	@Override
	public void addReportLog(CreditReportLog log) {
		creditReportLogDao.insertSelective(log);

	}

	@Override
	public CreditReportLog getReportLogDetail(int id) {

		return creditReportLogDao.selectByPrimaryKey(id);
	}

	@SuppressWarnings("unchecked")
	@Override
	public void createCreditReport(String absolutepath, String tybm, String qymc) throws Exception {

		Map<String, Object> detail = sContentService.getDetail("100000", tybm, "XYHC", null);

		String path = absolutepath + ResourcePath.CREDIT_REPORT_DIR + tybm + "/";

		String filePath = path + ResourcePath.CREDIT_REPORT_NAME;
		Hcbg latest = bgdzService.getLatest();
		String reportProducer = null;
		String reportNo = null;
		String reportStatment = null;
		String watermark = null;
		if (latest != null) {
			reportProducer = latest.getReportProducer();
			reportNo = latest.getReportNo();
			reportStatment = latest.getReportStatment();
			watermark = absolutepath + latest.getWatermarker();
		}

		File dirPath = new File(path);

		if (!dirPath.exists()) {

			dirPath.mkdirs();

		}

		Map<String, List<TableResult>> map = new HashMap<String, List<TableResult>>();

		for (TableResult tableResult : (List<TableResult>) detail.get("results")) {

			String categoryCode = tableResult.getCategoryCode();

			if (map.containsKey(categoryCode)) {

				List<TableResult> list = map.get(categoryCode);

				list.add(tableResult);

			} else {

				List<TableResult> rs = new ArrayList<TableResult>();

				rs.add(tableResult);

				map.put(categoryCode, rs);

			}

		}

		PdfUtils.createCreditCheckPdf(watermark, filePath, qymc, reportNo, reportProducer, reportStatment, map);

	}

	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Object> getReportData(String tybm, String kId) {

		String number = this.getReportSerials(kId, DateUtils.getCurrentTime());

		Map<String, Object> result = new HashMap<String, Object>();

		Map<String, Object> detail = sContentService.getDetail(kId, tybm, "XYHC", null);

		Map<String, List<TableResult>> map = new HashMap<String, List<TableResult>>();

		List<TableResult> assembleTableComponent = sSearchService
				.assembleTableComponent((List<TableResult>) detail.get("results"));

		for (TableResult tableResult : assembleTableComponent) {

			String categoryCode = tableResult.getCategoryCode();

			if (map.containsKey(categoryCode)) {

				List<TableResult> list = map.get(categoryCode);

				list.add(tableResult);

			} else {

				List<TableResult> rs = new ArrayList<TableResult>();

				rs.add(tableResult);

				map.put(categoryCode, rs);

			}

		}

		Hcbg latest = bgdzService.getLatest();

		latest.setReportNo(latest.getReportNo() + DateUtils.getStringOfTodayDate(DateUtils.SIMPLE_PATTERN) + number);

		result.put("tableData", map);

		result.put("elementData", latest);

		return result;

	}

	@Override
	public synchronized String getReportSerials(String kId, String currentTime) {

		int serialNumbe = creditReportDao.selectReportSerials(kId, currentTime) + 1;

		creditReportDao.addReportSerials(serialNumbe, kId, currentTime);

		if (serialNumbe > 999) {

			serialNumbe = serialNumbe - 999;

		}

		return new DecimalFormat("000").format(serialNumbe).toString();

	}

}
